package cn.mw.cmdb.entity;

import cn.mw.cmdb.view.InstanceInputFieldView;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.nacos.shaded.com.google.gson.Gson;
import com.google.common.base.Strings;
import com.google.gson.reflect.TypeToken;
import org.springframework.data.mongodb.core.query.Criteria;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static cn.mw.cmdb.view.InstanceListViewConverter.*;

public class PropertyTypeQRCode extends PropertyType<PropertyTypeQRCode, Object> {
    public static final String ID = "qrCode";

    public PropertyTypeQRCode() {
        setId(ID);
        setName("二维码");
        setSortNum(22);
    }

    @Override
    public Criteria doCriteria(CriteriaOpsType opsType, String name, Object value) {
        Criteria criteria = null;
        switch (opsType) {
            case in:
                if (value instanceof List) {
                    criteria = new Criteria(name).in(((List<?>) value).toArray());
                } else {
                    criteria = new Criteria(name).in(value);
                }
                break;
            case nin:
                if (value instanceof List) {
                    criteria = new Criteria(name).nin(((List<?>) value).toArray());
                } else {
                    criteria = new Criteria(name).nin(value);
                }
                break;
            case elemMatch:
                criteria = new Criteria(name).elemMatch(new Criteria().in(JSONArray.parse(strValueConvert(value))));
                break;
            case exist:
                criteria = new Criteria(name).exists((boolean) value);
                break;
            case ne:
                criteria = new Criteria(name).ne(value);
        }
        return criteria;
    }

    @Override
    public CriteriaOpsType getDefaultCriteriaOpsType() {
        return CriteriaOpsType.in;
    }

    @Override
    public PropertyTypeQRCode newObj() {
        return new PropertyTypeQRCode();
    }

    @Override
    public void refresh() {

    }

    @Override
    public Object getDefaultContextValue(Map<String, Object> context) {
        List fieldList = new ArrayList<>();
        if(context!=null && context.get(fieldListKey)!=null){
            Object fieldListObj = context.get(fieldListKey);
            if (fieldListObj != null && fieldListObj instanceof List) {
                fieldList = (List) fieldListObj;
            }
        }
        return fieldList;
    }

    @Override
    public Object lookValue(Object val, Map<String, Object> context) {
        Map ms = new HashMap();
        Object obj = context.get(dataListMap);
        Object propertyListObj = context.get(propertyListMapKey);
        Map<String, PropertyInfo> collectMap = new HashMap<>();
        if(propertyListObj!=null && propertyListObj instanceof List){
            List<PropertyInfo> propertyList = (List<PropertyInfo>) propertyListObj;
            collectMap = propertyList.stream().collect(Collectors.toMap(s ->s.getModelId() +"_"+ s.getId(), s -> s));
        }


        Object fieldListObj = context.get(fieldListKey);
        TypeToken<Map<String, String>> typeToken = new TypeToken<Map<String, String>>() {
        };
        Gson gson = new Gson();
        if (obj != null && obj instanceof Map && fieldListObj != null && fieldListObj instanceof List) {
            Map maps = (Map) obj;
            List fieldList = (List) fieldListObj;
            for (Object objMap : fieldList) {
                Map<String, String> map = gson.fromJson(JSON.toJSONString(objMap), typeToken.getType());
                String disPropertyId = map.get("id");
                String properTyName = map.get("name");
                //disPropertyId为 16523485125638_mw_instanceName;16523485125638为模型id，mw_instanceName为属性id
                if(!Strings.isNullOrEmpty(disPropertyId) && disPropertyId.length() > 2){
                    int i = disPropertyId.indexOf("_", 0);
                    String propertyId = disPropertyId.substring(i+1);
                    Object dataObj = maps.get(propertyId);
                    if(collectMap!=null && collectMap.containsKey(disPropertyId)){
                        PropertyInfo propertyInfo = collectMap.get(disPropertyId);
                        if(propertyInfo!=null && propertyInfo.getPropertyTypeRef()!=null){
                            String typeId = propertyInfo.getPropertyTypeRef().getTypeId();
                            Map<String, Object> contextParam = propertyInfo.getPropertyTypeRef().getContext();
                            PropertyType propertyType = PropertyTypeManage.getPropertyType(typeId);
                            dataObj = propertyType.exportValue(dataObj, contextParam);
                        }
                        ms.put(properTyName, dataObj);
                    }
                }
            }
        }
        return ms;
    }


    @Override
    public Object readValue(Object val, Map<String, Object> context) {
        return lookValue(val,context);
    }
}
